package com.alibaba.algo.apiimpl.user;

import com.alibaba.algo.cooperation.common.BaseResult;
import com.alibaba.algo.cooperation.usercomponent.service.user.SysRoleService;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.CreateRoleRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleDetailByCodeRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleDetailByIdRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleListByAppRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.SelectRoleListRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.req.user.UpdateRoleRequestVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectRoleDetailByCodeResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SelectRoleDetailByIdResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysOrgInfoVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysResourceResponseVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysRoleInfoVO;
import com.alibaba.algo.cooperation.usercomponent.vo.res.user.SysUserInfoVO;
import com.alibaba.algo.core.base.PagerEntity;
import com.alibaba.algo.core.base.YesOrNo;
import com.alibaba.algo.core.exception.BaseException;
import com.alibaba.algo.domain.user.SysEmployeeOrgDomain;
import com.alibaba.algo.domain.user.SysOrgRoleDomain;
import com.alibaba.algo.domain.user.SysResourceDomain;
import com.alibaba.algo.domain.user.SysRoleDomain;
import com.alibaba.algo.domain.user.SysRoleResourceDomain;
import com.alibaba.algo.domain.user.SysUserDomain;
import com.alibaba.algo.domain.user.SysUserRoleDomain;
import com.alibaba.algo.entity.user.SysOrgRole;
import com.alibaba.algo.entity.user.SysResource;
import com.alibaba.algo.entity.user.SysRole;
import com.alibaba.algo.entity.user.SysRoleResource;
import com.alibaba.algo.entity.user.SysUser;
import com.alibaba.algo.entity.user.SysUserRole;
import com.alibaba.algo.enums.SysRoleStateEnum;
import com.alibaba.algo.enums.SysRoleTypeEnum;
import com.alibaba.algo.exception.SysRoleErrorCode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 类SysRoleServiceImpl.java的实现描述：角色 serviceimpl
 *
 * @author nieganggang 2021-03-12 16:08:17
 */
@Slf4j
@RestController
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleDomain sysRoleDomain;

    @Autowired
    private SysRoleResourceDomain sysRoleResourceDomain;

    @Autowired
    private SysUserRoleDomain sysUserRoleDomain;

    @Autowired
    private SysOrgRoleDomain sysOrgRoleDomain;

    @Autowired
    private SysResourceDomain sysResourceDomain;

    @Autowired
    private SysUserDomain sysUserDomain;

    @Resource
    private SysEmployeeOrgDomain sysEmployeeOrgDomain;

    @Resource
    private SysUserCacheServiceImpl sysUserCacheService;

    /**
     * 新增角色
     *
     * @param createRoleRequestVO 角色信息
     * @return 结果
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult insert(CreateRoleRequestVO createRoleRequestVO) {
        if (createRoleRequestVO.getRoleType() == null) {
            createRoleRequestVO.setRoleType(SysRoleTypeEnum.PUBLIC_ROLE.getType());
        }
        // 校验字段唯一性
        this.checkRoleInfo(createRoleRequestVO.getRoleName(),
                createRoleRequestVO.getRoleCode(),
                createRoleRequestVO.getRoleDesc(),
                createRoleRequestVO.getRoleType(),
                createRoleRequestVO.getOrgIdList());

        //当是组织角色时，关联的用户列表需要都属于关联的组织
        List<Long> orgIdList = createRoleRequestVO.getOrgIdList();
        List<Long> userIdList = createRoleRequestVO.getUserIdList();
        //关联的组织只能有一个
        if (null != orgIdList && orgIdList.size() > 1) {
            throw new RuntimeException("关联的组织不能超过1个");
        }
        if (SysRoleTypeEnum.ORG_ROLE.getType().equals(createRoleRequestVO.getRoleType())) {
            if (userIdList != null && !userIdList.isEmpty() && !ObjectUtils.isEmpty(orgIdList)) {
                Long orgId = orgIdList.get(0);
                List<Long> orgUserList = sysEmployeeOrgDomain.selectCurAndLowerUserIdList(orgId);
                if (orgUserList == null || orgUserList.isEmpty()) {
                    throw new RuntimeException("关联的用户必须都属于指定的组织");
                }
                for (Long userId : userIdList) {
                    if (!orgUserList.contains(userId)) {
                        throw new RuntimeException("关联的用户必须都属于指定的组织");
                    }
                }
            }
        }
        SysRole sysRoleFromDB = sysRoleDomain.selectByRoleCodeWithIsDeleted(createRoleRequestVO.getRoleCode());
        SysRole sysRole;
        if(null != sysRoleFromDB){//存在做更新
            sysRole = sysRoleFromDB;
            BeanUtils.copyProperties(createRoleRequestVO, sysRole);
            sysRole.setIsDeleted(YesOrNo.N.name());
            sysRoleDomain.updateByIdWithIsDeleted(sysRole);
        }else{
            sysRole = new SysRole();
            BeanUtils.copyProperties(createRoleRequestVO, sysRole);
            // 角色状态
            sysRole.setRoleState(SysRoleStateEnum.VALID.getValue());
            sysRoleDomain.insert(sysRole);
        }
        Long roleId = sysRole.getId();
        // 资源列表
        List<Long> resourceIdList = createRoleRequestVO.getResourceIdList();

        // 绑定资源
        this.addRoleAndResourceRelated(roleId, resourceIdList);

        //绑定继承的公共角色资源
        if (!ObjectUtils.isEmpty(sysRole) && null != sysRole.getInheritedPublicRoleId() && sysRole.getInheritedPublicRoleId() >= 0) {
            List<Long> publicResourceIdList = new ArrayList<>();
            List<SysResource> resourceList = sysRoleResourceDomain.selectResourceListByRoleId(sysRole.getInheritedPublicRoleId());
            if (!ObjectUtils.isEmpty(resourceList)) {
                resourceList.forEach(item -> {
                    publicResourceIdList.add(item.getResourceId());
                });
            }
            if (!ObjectUtils.isEmpty(publicResourceIdList)) {
                this.addRoleAndResourceRelated(roleId, publicResourceIdList);
            }
        }

        this.addOrgAndRoleRelated(roleId, orgIdList);

        this.addUserAndRoleRelated(roleId, userIdList);

        // 删除缓存，新增角色选择了人员，那么对应人员的角色信息就发生了变化，因此需要删除
        if (!CollectionUtils.isEmpty(userIdList)) {
            sysUserCacheService.deleteUserFromCacheByRoleUpdate(roleId);
        }
        return BaseResult.buildSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult insertOrgRole(CreateRoleRequestVO createRoleRequestVO) {
        if (createRoleRequestVO.getRoleType() == null) {
            createRoleRequestVO.setRoleType(SysRoleTypeEnum.ORG_ROLE.getType());
        }
        // 校验字段唯一性
        this.checkRoleInfo(createRoleRequestVO.getRoleName(),
                createRoleRequestVO.getRoleCode(),
                createRoleRequestVO.getRoleDesc(),
                createRoleRequestVO.getRoleType(),
                createRoleRequestVO.getOrgIdList());

        List<Long> orgIdList = createRoleRequestVO.getOrgIdList();
        //根据code查询角色是否存在(逻辑删除)
        SysRole sysRoleFromDB = sysRoleDomain.selectByRoleCodeWithIsDeleted(createRoleRequestVO.getRoleCode());
        SysRole sysRole;
        if(null != sysRoleFromDB){//存在做更新
            sysRole = sysRoleFromDB;
            BeanUtils.copyProperties(createRoleRequestVO, sysRole);
            sysRole.setIsDeleted(YesOrNo.N.name());
            sysRoleDomain.updateByIdWithIsDeleted(sysRole);
        }else{
            sysRole = new SysRole();
            BeanUtils.copyProperties(createRoleRequestVO, sysRole);
            // 角色状态
            sysRole.setRoleState(SysRoleStateEnum.VALID.getValue());
            sysRoleDomain.insert(sysRole);
        }
        Long roleId = sysRole.getId();
        //绑定继承的公共角色资源
        if (!ObjectUtils.isEmpty(sysRole) && null != sysRole.getInheritedPublicRoleId() && sysRole.getInheritedPublicRoleId() >= 0) {
            List<Long> publicResourceIdList = new ArrayList<>();
            List<SysResource> resourceList = sysRoleResourceDomain.selectResourceListByRoleId(sysRole.getInheritedPublicRoleId());
            if (!ObjectUtils.isEmpty(resourceList)) {
                resourceList.forEach(item -> {
                    publicResourceIdList.add(item.getResourceId());
                });
            }
            if (!ObjectUtils.isEmpty(publicResourceIdList)) {
                this.addRoleAndResourceRelated(roleId, publicResourceIdList);
            }
        }

        this.addOrgAndRoleRelated(roleId, orgIdList);
        // 用户角色信息绑定
        this.updateUserRoleRelatedByOrgRole(roleId, orgIdList);

        // 删除缓存，新增角色选择了组织，那么对应组织下人员用户的角色信息就发生了变化，因此需要删除
        if (!CollectionUtils.isEmpty(orgIdList)) {
            sysUserCacheService.deleteUserFromCacheByRoleUpdate(roleId);
        }
        return BaseResult.buildSuccess();
    }

    /**
     * 建立角色和资源的关联关系
     *
     * @param roleId         角色标识
     * @param resourceIdList 资源标识
     */
    private void addRoleAndResourceRelated(Long roleId, List<Long> resourceIdList) {
        // 新增角色和资源的关联关系
        if (!CollectionUtils.isEmpty(resourceIdList)) {
            for (Long resourceId : resourceIdList) {
                SysRoleResource sysRoleResource = new SysRoleResource();
                sysRoleResource.setRoleId(roleId);
                sysRoleResource.setResourceId(resourceId);
                sysRoleResourceDomain.insert(sysRoleResource);
            }
        }
    }

    private void addOrgAndRoleRelated(Long roleId, List<Long> orgIdList) {
        if (!CollectionUtils.isEmpty(orgIdList)) {
            for (Long orgId : orgIdList) {
                if (null != orgId) {
                    SysOrgRole temp = new SysOrgRole();
                    temp.setRoleId(roleId);
                    temp.setOrgId(orgId);
                    sysOrgRoleDomain.insert(temp);
                }
            }
        }
    }

    private void addUserAndRoleRelated(Long roleId, List<Long> userIdList) {
        if (!CollectionUtils.isEmpty(userIdList)) {
            for (Long userId : userIdList) {
                SysUserRole temp = new SysUserRole();
                temp.setRoleId(roleId);
                temp.setUserId(userId);
                sysUserRoleDomain.insert(temp);
            }
        }
    }

    /**
     * 校验角色名称、角色编码,全局唯一
     *
     * @param roleName 角色名称
     * @param roleDesc 角色描述
     */
    private void checkRoleInfo(String roleName, String roleCode, String roleDesc, Integer roleType, List<Long> orgIdList) {
        // 校验角色名称
        if (!StringUtils.isEmpty(roleName)) {
            SysRole sysRoleName = new SysRole();
            sysRoleName.setRoleName(roleName);
            List<SysRole> sysRoleList = sysRoleDomain.listByPara(sysRoleName, null);
            if (!CollectionUtils.isEmpty(sysRoleList)) {
                throw new BaseException(SysRoleErrorCode.ROLE_NAME_REPEAT.getCode(), SysRoleErrorCode.ROLE_NAME_REPEAT.getMessage());
            }
        }
        // 校验角色编码
        if (!StringUtils.isEmpty(roleCode)) {
            SysRole sysRoleCode = new SysRole();
            sysRoleCode.setRoleCode(roleCode);
            List<SysRole> sysRoleList = sysRoleDomain.listByPara(sysRoleCode, null);
            if (!CollectionUtils.isEmpty(sysRoleList)) {
                throw new BaseException(SysRoleErrorCode.ROLE_CODE_REPEAT.getCode(), SysRoleErrorCode.ROLE_CODE_REPEAT.getMessage());
            }
        }
        // 校验描述长度
        if (StringUtils.isNotEmpty(roleDesc) && (roleDesc.length() > 255)) {
            throw new BaseException(SysRoleErrorCode.ROLE_DESC_IS_TOO_LONG.getCode(), SysRoleErrorCode.ROLE_DESC_IS_TOO_LONG.getMessage());
        }
    }

    /**
     * 删除此角色
     *
     * @param roleIdList 主键标识列表
     * @return 删除结果
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult delete(List<Long> roleIdList) {
        // 批量删除
        for (Long roleId : roleIdList) {
            this.deleteRole(roleId);
        }
        return BaseResult.buildSuccess();
    }

    /**
     * 删除角色
     *
     * @param roleId 角色标识
     */
    private void deleteRole(Long roleId) {
        if (null == roleId || roleId <= 0) {
            throw new BaseException(SysRoleErrorCode.ROLE_ID_IS_ILLEGAL.getCode(), SysRoleErrorCode.ROLE_ID_IS_ILLEGAL.getMessage());
        }
        // 查询当前角色下的用户列表
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setRoleId(roleId);
        List<SysUserRole> userRoleList = sysUserRoleDomain.listByPara(sysUserRole, null);
        // 删除角色(如果还有员工或组织允许删除，关联关系也一并清除)
        SysRole sysRole = new SysRole();
        sysRole.setId(roleId);
        sysRole.setIsDeleted(YesOrNo.Y.name());
        sysRole.setGmtModified(LocalDateTime.now());
        sysRoleDomain.updateById(sysRole);
        SysOrgRole sysOrgRole = new SysOrgRole();
        sysOrgRole.setRoleId(roleId);
        sysOrgRole.setIsDeleted(YesOrNo.Y.name());
        sysOrgRole.setGmtModified(LocalDateTime.now());
        sysOrgRoleDomain.updateByRoleId(sysOrgRole);
        //删除角色人员关系
        sysUserRoleDomain.batchDeleteUserRoleRelated(roleId);
        // 删除角色关联的菜单角色(resourceType字段已经不存在，弃用)
        //this.deleteMenuResourceByRoleId(roleId);
        // 说明：此处无需清理缓存，因为前面有限制条件，角色下有用户不允许删除角色，而缓存基于用户员工建立
    }

    /**
     * 更新角色信息
     *
     * @param updateRoleRequestVO 更新信息
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult update(UpdateRoleRequestVO updateRoleRequestVO) {
        // 参数合法性检查
        if (null == updateRoleRequestVO) {
            log.info("SysRoleServiceImpl.update updateRoleRequestVO is null");
            return BaseResult.buildError("参数不能为空");
        }
        if (null == updateRoleRequestVO.getId() || updateRoleRequestVO.getId() <= 0) {
            log.info("SysRoleServiceImpl.update updateRoleRequestVO.id is null");
            return BaseResult.buildError("角色ID不能为空");
        }
        log.info("SysRoleServiceImpl.update,updateRoleRequestVO:{}", JSONObject.toJSONString(updateRoleRequestVO));

        SysRole oriRole = sysRoleDomain.getById(updateRoleRequestVO.getId());
        if (oriRole.getRoleName().equals(updateRoleRequestVO.getRoleName())) {
            updateRoleRequestVO.setRoleName(null);
        }
        if (oriRole.getRoleCode().equals(updateRoleRequestVO.getRoleCode())) {
            updateRoleRequestVO.setRoleCode(null);
        }
        if (updateRoleRequestVO.getRoleType() == null) {
            updateRoleRequestVO.setRoleType(SysRoleTypeEnum.PUBLIC_ROLE.getType());
        }
        // 校验字段唯一性
        this.checkRoleInfo(updateRoleRequestVO.getRoleName(),
                updateRoleRequestVO.getRoleCode(),
                updateRoleRequestVO.getRoleDesc(),
                updateRoleRequestVO.getRoleType(),
                updateRoleRequestVO.getOrgIdList());

        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(updateRoleRequestVO, sysRole);
        int iRtn = sysRoleDomain.updateById(sysRole);
        //sysRoleResourceDomain.updateRelatedByRoleId(sysRole.getId(), updateRoleRequestVO.getResourceIdList());
        sysOrgRoleDomain.updateRelatedByRoleId(sysRole.getId(), updateRoleRequestVO.getOrgIdList());
        sysUserRoleDomain.updateRelatedByRoleId(sysRole.getId(), updateRoleRequestVO.getUserIdList());

        if (iRtn > 0) {
            // 删除缓存，涉及情况：1、角色编码或名称修改；2、角色和人的关系修改；
            sysUserCacheService.deleteUserFromCacheByRoleUpdate(oriRole.getId());
        }
        return BaseResult.buildSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult updateRoleBasicInfo(UpdateRoleRequestVO updateRoleRequestVO){
        // 参数合法性检查
        if (null == updateRoleRequestVO) {
            log.info("SysRoleServiceImpl.updateBasicInfo updateRoleRequestVO is null");
            return BaseResult.buildError("参数不能为空");
        }
        if (null == updateRoleRequestVO.getId() || updateRoleRequestVO.getId() <= 0) {
            log.info("SysRoleServiceImpl.updateBasicInfo updateRoleRequestVO.id is null");
            return BaseResult.buildError("角色ID不能为空");
        }
        log.info("SysRoleServiceImpl.updateBasicInfo,updateRoleRequestVO:{}", JSONObject.toJSONString(updateRoleRequestVO));

        SysRole oriRole = sysRoleDomain.getById(updateRoleRequestVO.getId());
        if (oriRole.getRoleName().equals(updateRoleRequestVO.getRoleName())) {
            updateRoleRequestVO.setRoleName(null);
        }
        if (oriRole.getRoleCode().equals(updateRoleRequestVO.getRoleCode())) {
            updateRoleRequestVO.setRoleCode(null);
        }
        if (updateRoleRequestVO.getRoleType() == null) {
            updateRoleRequestVO.setRoleType(SysRoleTypeEnum.PUBLIC_ROLE.getType());
        }
        // 校验字段唯一性
        this.checkRoleInfo(updateRoleRequestVO.getRoleName(),
                updateRoleRequestVO.getRoleCode(),
                updateRoleRequestVO.getRoleDesc(),
                updateRoleRequestVO.getRoleType(),
                updateRoleRequestVO.getOrgIdList());

        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(updateRoleRequestVO, sysRole);
        int iRtn = sysRoleDomain.updateById(sysRole);
        if (iRtn > 0) {
            // 删除缓存，涉及情况：1、角色编码或名称修改；2、角色和人的关系修改；
            sysUserCacheService.deleteUserFromCacheByRoleUpdate(oriRole.getId());
        }
        return BaseResult.buildSuccess();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult updateRoleUser(UpdateRoleRequestVO updateRoleRequestVO,int flag){
        // 参数合法性检查
        if (null == updateRoleRequestVO) {
            log.info("SysRoleServiceImpl.updateRoleUser updateRoleRequestVO is null");
            return BaseResult.buildError("参数不能为空");
        }
        if (null == updateRoleRequestVO.getId() || updateRoleRequestVO.getId() <= 0) {
            log.info("SysRoleServiceImpl.updateRoleUser updateRoleRequestVO.id is null");
            return BaseResult.buildError("角色ID不能为空");
        }
        log.info("SysRoleServiceImpl.updateRoleUser,updateRoleRequestVO:{}", JSONObject.toJSONString(updateRoleRequestVO));

        SysRole oriRole = sysRoleDomain.getById(updateRoleRequestVO.getId());
        if(oriRole==null){
            return BaseResult.buildError("该角色已经不存在，不能进行授权用户操作");
        }
        sysUserRoleDomain.updateRelatedByRoleIdV2(updateRoleRequestVO.getId(), updateRoleRequestVO.getUserIdList(),flag);
        return BaseResult.buildSuccess();
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public BaseResult updateOrgRole(UpdateRoleRequestVO updateRoleRequestVO) {
        // 参数合法性检查
        if (null == updateRoleRequestVO) {
            log.info("SysRoleServiceImpl.updateOrgRole updateRoleRequestVO is null");
            return BaseResult.buildError("参数不能为空");
        }
        if (null == updateRoleRequestVO.getId() || updateRoleRequestVO.getId() <= 0) {
            log.info("SysRoleServiceImpl.updateOrgRole updateRoleRequestVO.id is null");
            return BaseResult.buildError("角色ID不能为空");
        }
        log.info("SysRoleServiceImpl.updateOrgRole,updateRoleRequestVO:{}", JSONObject.toJSONString(updateRoleRequestVO));

        SysRole oriRole = sysRoleDomain.getById(updateRoleRequestVO.getId());
        if (oriRole.getRoleName().equals(updateRoleRequestVO.getRoleName())) {
            updateRoleRequestVO.setRoleName(null);
        }
        if (oriRole.getRoleCode().equals(updateRoleRequestVO.getRoleCode())) {
            updateRoleRequestVO.setRoleCode(null);
        }
        if (updateRoleRequestVO.getRoleType() == null) {
            updateRoleRequestVO.setRoleType(SysRoleTypeEnum.ORG_ROLE.getType());
        }
        // 校验字段唯一性
        this.checkRoleInfo(updateRoleRequestVO.getRoleName(),
                updateRoleRequestVO.getRoleCode(),
                updateRoleRequestVO.getRoleDesc(),
                updateRoleRequestVO.getRoleType(),
                updateRoleRequestVO.getOrgIdList());

        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(updateRoleRequestVO, sysRole);
        int iRtn = sysRoleDomain.updateById(sysRole);

        sysOrgRoleDomain.updateRelatedByRoleId(sysRole.getId(), updateRoleRequestVO.getOrgIdList());
        //用户角色信息绑定
        this.updateUserRoleRelatedByOrgRole(sysRole.getId(), updateRoleRequestVO.getOrgIdList());

        if (iRtn > 0) {
            // 删除缓存，涉及情况：1、角色编码或名称修改；2、角色和人的关系修改；
            sysUserCacheService.deleteUserFromCacheByRoleUpdate(oriRole.getId());
        }
        return BaseResult.buildSuccess();
    }

    /**
     * 删除角色下的资源
     *
     * @param roleId 资源标识
     */
    private void deleteMenuResourceByRoleId(Long roleId) {
        List<SysRoleResource> roleResourceList = sysRoleResourceDomain.selectMenuResourceListByRoleId(roleId);
        if (!ObjectUtils.isEmpty(roleResourceList)) {
            for (SysRoleResource roleResource : roleResourceList) {
                roleResource.setIsDeleted(YesOrNo.Y.name());
                sysRoleResourceDomain.updateById(roleResource);
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public BaseResult selectOrgRolePage(SelectRoleListRequestVO selectRoleListRequestVO) {
        PagerEntity pagerEntity = sysRoleDomain.selectOrgRolePage(selectRoleListRequestVO);
        return BaseResult.buildSuccess(pagerEntity);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public BaseResult selectPage(SelectRoleListRequestVO selectRoleListRequestVO) {
        PagerEntity pagerEntity = sysRoleDomain.selectPage(selectRoleListRequestVO);
        return BaseResult.buildSuccess(pagerEntity);
    }

    public BaseResult permissionSelect(SelectRoleListRequestVO selectRoleListRequestVO) {
        PagerEntity pagerEntity = sysRoleDomain.permissionSelect(selectRoleListRequestVO);
        return BaseResult.buildSuccess(pagerEntity);
    }

    /**
     * 根据角色名称或角色编码查询角色列表
     *
     * @param vo 角色名称或角色编码
     * @return 角色列表
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public BaseResult selectRoleListByKey(SelectRoleDetailByCodeRequestVO vo) {
        SysRole sysRoleCon = new SysRole();
        sysRoleCon.setRoleCodeKey(vo.getRoleCodeKey());
        sysRoleCon.setRoleNameKey(vo.getRoleNameKey());
        List<SysRole> roleList = sysRoleDomain.listByPara(sysRoleCon, null);
        List<SelectRoleDetailByCodeResponseVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roleList)) {
            for (SysRole sysRole : roleList) {
                SelectRoleDetailByCodeResponseVO responseVO = new SelectRoleDetailByCodeResponseVO();
                responseVO.setRoleId(sysRole.getId());
                responseVO.setRoleCode(sysRole.getRoleCode());
                responseVO.setRoleName(sysRole.getRoleName());
                result.add(responseVO);
            }
        }
        return BaseResult.buildSuccess(result);
    }


    @Override
    public SelectRoleDetailByIdResponseVO selectOrgRoleDetailById(SelectRoleDetailByIdRequestVO vo) {
        Long roleId = vo.getRoleId();
        SysRole sysRole = sysRoleDomain.getById(roleId);
        SelectRoleDetailByIdResponseVO resVO = new SelectRoleDetailByIdResponseVO();
        resVO.setRoleId(sysRole.getId());
        resVO.setRoleCode(sysRole.getRoleCode());
        resVO.setRoleName(sysRole.getRoleName());
        resVO.setRoleState(sysRole.getRoleState());
        resVO.setRoleDesc(sysRole.getRoleDesc());
        resVO.setRoleType(sysRole.getRoleType());
        resVO.setExpireStarttime(sysRole.getExpireStarttime());
        resVO.setExpireEndtime(sysRole.getExpireEndtime());
        Long inheritedPublicRoleId = sysRole.getInheritedPublicRoleId();
        if (inheritedPublicRoleId != null) {
            resVO.setInheritedPublicRoleId(inheritedPublicRoleId);
            SysRole inheritedPublicRole = sysRoleDomain.getById(inheritedPublicRoleId);
            if (!ObjectUtils.isEmpty(inheritedPublicRole)) {
                SysRoleInfoVO temp = new SysRoleInfoVO();
                temp.setRoleId(inheritedPublicRoleId);
                if (!ObjectUtils.isEmpty(inheritedPublicRole.getRoleName())) {
                    temp.setRoleName(inheritedPublicRole.getRoleName());
                }
                resVO.setInheritedPublicRole(temp);
            }
        }

        List<SysOrgInfoVO> orgList = sysOrgRoleDomain.selectOrgListByRoleId(roleId);
        resVO.setOrgList(orgList);

        return resVO;
    }

    @Override
    public SelectRoleDetailByIdResponseVO selectDetailById(SelectRoleDetailByIdRequestVO vo) {
        Long roleId = vo.getRoleId();
        SysRole sysRole = sysRoleDomain.getById(roleId);
        SelectRoleDetailByIdResponseVO resVO = new SelectRoleDetailByIdResponseVO();
        resVO.setRoleId(sysRole.getId());
        resVO.setRoleCode(sysRole.getRoleCode());
        resVO.setRoleName(sysRole.getRoleName());
        resVO.setRoleState(sysRole.getRoleState());
        resVO.setRoleDesc(sysRole.getRoleDesc());
        resVO.setRoleType(sysRole.getRoleType());
        //resVO.setExpireEndtime(sysRole.getExpireEndtime());
        //resVO.setExpireStarttime(sysRole.getExpireStarttime());
        Long inheritedPublicRoleId = sysRole.getInheritedPublicRoleId();
        if (inheritedPublicRoleId != null) {
            resVO.setInheritedPublicRoleId(inheritedPublicRoleId);
            SysRole inheritedPublicRole = sysRoleDomain.getById(inheritedPublicRoleId);
            //避免后台删除父角色导致空指针
            if (!ObjectUtils.isEmpty(inheritedPublicRole)) {
                SysRoleInfoVO temp = new SysRoleInfoVO();
                temp.setRoleId(inheritedPublicRoleId);
                if (!ObjectUtils.isEmpty(inheritedPublicRole.getRoleName())) {
                    temp.setRoleName(inheritedPublicRole.getRoleName());
                }
                resVO.setInheritedPublicRole(temp);
            }
        }
        List<SysUserInfoVO> userList = sysUserRoleDomain.selectUserListByRoleId2(roleId, null);
        //避免后台单独删除用户，没有删除关联角色的情况
        userList.remove(null);
        //空数据从list中删除
        if (!ObjectUtils.isEmpty(userList)) {
            Iterator<SysUserInfoVO> iterator = userList.iterator();
            while (iterator.hasNext()) {
                SysUserInfoVO sysUser = iterator.next();
                if (ObjectUtils.isEmpty(sysUser) || ObjectUtils.isEmpty(sysUser.getUserId()) || sysUser.getUserId() <= 0) {
                    iterator.remove();
                }
            }
        }
        resVO.setUserList(userList);

        List<SysOrgInfoVO> orgList = sysOrgRoleDomain.selectOrgListByRoleId(roleId);
        resVO.setOrgList(orgList);

        List<SysResourceResponseVO> resourceList = new ArrayList<>();
        resVO.setResourceList(resourceList);

        /*
        List<SysResource> list = sysRoleResourceDomain.selectResourceListByRoleId(roleId);
        List<SysResourceResponseVO> resourceList = new ArrayList<>();
        if (list != null) {
            for (SysResource temp : list) {
                SysResourceResponseVO vo1 = new SysResourceResponseVO();
                vo1.setId(temp.getId());
                vo1.setParentId(temp.getParentId());
                vo1.setResourceCode(temp.getResourceCode());
                vo1.setResourceType(temp.getResourceType());
                vo1.setResourceName(temp.getResourceName());
                resourceList.add(vo1);
            }
        }
        resVO.setResourceList(resourceList);
        */
        return resVO;
    }

    /**
     * 查询全量角色列表
     *
     * @return 角色列表
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public BaseResult selectList(SelectRoleListByAppRequestVO vo) {
        SysRole sysRole = new SysRole();
        sysRole.setAppCode(vo.getAppCode());
        LinkedHashMap<String, Object> sortMap = new LinkedHashMap<String, Object>();
        sortMap.put("id", "desc");
        List<SysRole> sysRoleList = sysRoleDomain.listByPara(sysRole, sortMap);
        List<SysRoleInfoVO> resVOList = new ArrayList<>();
        sysRoleList.forEach(s -> {
            SysRoleInfoVO resVO = new SysRoleInfoVO();
            resVO.setRoleId(s.getId());
            resVO.setRoleName(s.getRoleName());
            resVOList.add(resVO);
        });
        return BaseResult.buildSuccess(resVOList);
    }

    private void updateUserRoleRelatedByOrgRole(Long roleId, List<Long> orgIdList) {
        log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole begin");
        if (null == roleId) {
            log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole roleId is null");
            return;
        }
        if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(orgIdList)){
            log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole roleId={}, orgIdList={}", roleId, JSON.toJSONString(orgIdList));
            //1、找出组织下的人员清单
            List<SysUser> sysUserList = sysUserDomain.selectUserListByOrgIds(orgIdList);
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(sysUserList)) {
                log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole sysUserList is empty");
                return;
            }
            log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole sysUserList size={}", sysUserList.size());
            //2、分批更新角色和人员关系状态
            sysUserRoleDomain.mergeUserRoleRelated(roleId, sysUserList);
            log.info("SysRoleServiceImpl updateUserRoleRelatedByOrgRole end {}",System.lineSeparator());
        }
    }

    @Override
    public BaseResult updateUserRoleRelatedByOrgRole() {
        //1、查询出有效的组织角色清单
        List<SysOrgRole> sysOrgRoleList = sysOrgRoleDomain.listByPara(new SysOrgRole(), null);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(sysOrgRoleList)) {
            log.info("refreshUserRoleRelated sysOrgRoleList is empty");
            return BaseResult.buildSuccess();
        }

        //2、转换为一Role对多Org结构
        Map<Long, List<Long>> roleOrgMap = new HashMap<>();
        for (SysOrgRole sysOrgRole : sysOrgRoleList) {
            if (!roleOrgMap.containsKey(sysOrgRole.getRoleId())) {
                roleOrgMap.put(sysOrgRole.getRoleId(), new ArrayList<>());
            }
            roleOrgMap.get(sysOrgRole.getRoleId()).add(sysOrgRole.getOrgId());
        }

        //3、刷新组织下用户和角色的关系
        for (Map.Entry<Long, List<Long>> entry : roleOrgMap.entrySet()) {
            updateUserRoleRelatedByOrgRole(entry.getKey(), entry.getValue());
        }
        return BaseResult.buildSuccess();
    }
}
